KNOX-3330: Refactor LDAP Proxy configuration to support multiple backends#1240
KNOX-3330: Refactor LDAP Proxy configuration to support multiple backends#1240handavid wants to merge 3 commits into
Conversation
Test Results21 tests 21 ✅ 1s ⏱️ Results for commit 33fe1fe. |
…ends Gateway server configurations are updated to use 'gateway.ldap.interceptor.*' instead of 'gateway.ldap.backend.*' to allow specifying multiple types of interceptors as well as multiple backends to the LDAP proxy. BackendFactory has been modified to use the java ServiceLoader to load a factory for a backend class instead of a backend instance directly. This allows multiple backends of the same class to be configured. InterceptorFactory has been implemented following the same pattern. GroupLookupInterceptor is renamed to UserSearchInterceptor to more accurately describe what it does. Multiple UserSearchInterceptors can be configured with each forwarding the search to its backend and appending the results. A DuplicateUserFilteringInterceptor has been implemented that will filter out search Entries with the same UID that are returned from different backends.
33fe1fe to
dd9de8d
Compare
|
rebased and fixed conflicts |
smolnar82
left a comment
There was a problem hiding this comment.
I'll keep the review later today.
smolnar82
left a comment
There was a problem hiding this comment.
Another batch of comments.
I'll review the tests tomorrow.
| List<Entry> entries = new ArrayList<>(); | ||
| entries.addAll(backend.searchUsers(userSearchString, schemaManager)); | ||
| return entries; |
There was a problem hiding this comment.
Why not simply: return backend.searchUsers(userSearchString, schemaManager)?
In fact, if this is a simple inline backend invocation, why we have this private method at all? No any particular check, logic, etc...in here.
There was a problem hiding this comment.
removed. this was a result of refactoring some intermediate changes.
| } | ||
|
|
||
| private Entry getUser(String username) throws Exception { | ||
| return backend.getUser(username, schemaManager); |
There was a problem hiding this comment.
The same as above: I don't think this private method is necessary.
| DirectoryService directoryService; | ||
| private LdapServer ldapServer; | ||
| private LdapBackend backend; | ||
| private List<Interceptor> interceptors = new ArrayList<>(); |
There was a problem hiding this comment.
This is redundant, as you initialize interceptors anyway (i.e. not simply add entries into it).
See new line 80: this.interceptors = createInterceptors(config)
|
|
||
| @Override | ||
| public String getType() { | ||
| return "backend"; |
There was a problem hiding this comment.
nit: Should be a constant (we could reuse it in KnoxLdapManager, see my comment about not using the instanceof operator below).
| // Add our configured interceptors | ||
| SchemaManager schemaManager = directoryService.getSchemaManager(); | ||
| for (Interceptor interceptor : interceptors) { | ||
| if (interceptor instanceof UserSearchInterceptor) { |
There was a problem hiding this comment.
I personally am not a big fan of the instanceof operator, so this feel free to ignore this comment :)
It might be an option to store the interceptors above in a Map<String, Interceptor>, where the key is the interceptor type. If that was the case, we could simply check if the Map.Entry.key.equals("backend") (this is where my comment about creating the backend interceptor type constant would be useful).
There was a problem hiding this comment.
moved to get the remoteBaseDns from GatewayConfig directly since config is available to the KnoxLDAPServerManager
| if (!baseDns.contains(remoteBaseDn)) { | ||
| //create partition | ||
| String id = backend.getName().replaceAll("\\s+", ""); | ||
| JdbmPartition remotePartition = new JdbmPartition(schemaManager, directoryService.getDnFactory()); | ||
| remotePartition.setId(id); | ||
| remotePartition.setSuffixDn(new Dn(schemaManager, remoteBaseDn)); | ||
| remotePartition.setPartitionPath(new File(workDir, id).toURI()); | ||
| directoryService.addPartition(remotePartition); | ||
| baseDns.add(remoteBaseDn); | ||
| } |
There was a problem hiding this comment.
nit: a new private method (addRemotePartition, for instance) would increase the readability of this part of the code.
| <property> | ||
| <name>gateway.ldap.backend.file.dataFile</name> | ||
| <name>gateway.ldap.interceptor.ldapfile.backendType</name> | ||
| <value>ldap</value> |
| <!-- LDAP proxy backend configuration (gateway.ldap.interceptor.<interceptorName>.backendType=ldap) --> | ||
| <!-- This backend proxies to an external LDAP server (e.g., demo LDAP) --> | ||
| <!-- | ||
| Example 1: Using Knox demo LDAP server (default port 33389) |
There was a problem hiding this comment.
I'm not sure I like the idea of putting all these samples in the gateway-site.xml here.
We should rather create the new section in our user guide (see the knox-site module), and add all these sample configs there.
There was a problem hiding this comment.
I'm fixing the existing configs here for my config changes. should we remove the whole ldap proxy-related block?
I was waiting for #1227 to be merged before updating the documentation
KNOX-3330 - Refactor Knox LDAP Proxy configuration and implementation to allow multiple backends to be simultaneously configured
What changes were proposed in this pull request?
Gateway server configurations are updated to use 'gateway.ldap.interceptor.' instead of 'gateway.ldap.backend.' to allow specifying multiple types of interceptors as well as multiple backends to the LDAP proxy.
BackendFactory has been modified to use the java ServiceLoader to load a factory for a backend class instead of a backend instance directly. This allows multiple backends of the same class to be configured. InterceptorFactory has been implemented following the same pattern.
GroupLookupInterceptor is renamed to UserSearchInterceptor to more accurately describe what it does. Multiple UserSearchInterceptors can be configured with each forwarding the search to its backend and appending the results.
A DuplicateUserFilteringInterceptor has been implemented that will filter out search Entries with the same UID that are returned from different backends.
How was this patch tested?
Unit tests were updated.
Changes were manually tested against the test ldap server and an AD that I have access to.
The following configuration was added to the gateway-site.xml
Integration Tests
No integration test changes. PR can be updated after #1236 is merged
UI changes
no UI changes